namespace MoreLinq.Test.Async;

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

partial class TestExtensions
{
    public static WatchableEnumerator<T> AsWatchable<T>(this IAsyncEnumerator<T> source) => new(source);
}

sealed class WatchableEnumerator<T>(IAsyncEnumerator<T> source) :
    IAsyncEnumerator<T>
{
    readonly IAsyncEnumerator<T> source = source ?? throw new ArgumentNullException(nameof(source));

    public event EventHandler? Disposed;
    public event EventHandler<bool>? MoveNextCalled;

    public T Current => this.source.Current;

    public async ValueTask<bool> MoveNextAsync()
    {
        var moved = await this.source.MoveNextAsync();
        MoveNextCalled?.Invoke(this, moved);
        return moved;
    }

    public async ValueTask DisposeAsync()
    {
        await this.source.DisposeAsync();
        Disposed?.Invoke(this, EventArgs.Empty);
    }
}
